import React, { useState, useEffect, useMemo } from 'react';
import { action_del, tp_list, reload, action_add, update, action_swap, action_edit } from './cmd';
import { DlgMove, DlgVal } from './ctl';
import { loc, Chip, KFile, filter_row, WaitUmd, useCmd, is_empty, obj_str, MCmd, d_sort_num, obj_int, PanelFind, useHigh, Btn, GridTable } from 'sui';

const FieldView = ({ title, fix, mod }) => {
    const [open_val, openVal] = useState(false);
    const [open_move, openMove] = useState(false);
    const [fix_set, fixSet] = useState(new Set());
    const high = useHigh(210, 100);
    const umd = useCmd();

    useEffect(() => {
        if (is_empty(fix)) {
            fixSet(new Set());
        }
        else {
            const set = new Set();
            fix.forEach(d => set.add(obj_str(d, "sn")));

            fixSet(set);
        }

        reload(null, umd, mod, fix);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [fix, mod]);

    const getRow = useMemo(() => {
        const lst = ["sn", "name"];
        return filter_row(umd.value, lst, umd.filter);
    }, [umd.value, umd.filter]);

    const act = {
        "add": v => {
            const ret = action_add(v, umd);
            update(umd, mod, ret, fix);
        },
        "edit": v => {
            const ret = action_edit(v, umd);
            update(umd, mod, ret, fix);
        },
        "swap": v => {
            const ret = action_swap(v, umd);
            if (!ret) {
                return;
            }

            update(umd, mod, ret, fix);
        }
    };

    const pact = {
        "add": v => openVal(true),
        "edit": v => openVal(true),
        "swap": v => openMove(true),
    };

    const hDel = (val) => {
        const ret = action_del(val, umd);
        if (!ret) {
            return;
        }

        update(umd, mod, ret, fix);
    };

    const hImport = (ret) => {
        const set = new Set();

        for (let i = 0; i < ret.length; i++) {
            const d = ret[i];

            const index = obj_int(d, "index");
            const sn = obj_str(d, "sn");
            const name = obj_str(d, "name");

            if (set.has(sn)) {
                umd.setErr(`${loc("l_620")}: ${sn}`);
                return;
            }

            if (!index || !sn || !name) {
                umd.setErr(`${loc("l_276")}, index: ${index}, sn: ${sn}, name: ${name}`);
                return;
            }

            d["index"] = index;
        }

        d_sort_num(ret, "index");

        update(umd, mod, ret, fix);
    };

    const col = [
        {name: loc("l_238"), key: 'e_opt', width: 210, formatter: (props) => {
            const d = props.row;

            const getDel = () => {
                if (fix_set.has(obj_str(d, "sn"))) {
                    return null;
                }

                return <MCmd itype="del" hcmd={() => hDel(d)}/>;
            };

            return (
                <div className="inline-flex">
                    <MCmd itype="add" hcmd={() => umd.pact(pact, null, "add", {tp: "add", cur: d.index, opt: "N"})}/>
                    <MCmd itype="edit" hcmd={() => umd.pact(pact, d, "edit", {tp: "edit", cur: d.index})}/>
                    <MCmd itype="swap" hcmd={() => umd.pact(pact, d, "swap", {tp: "swap", cur: d.index})}/>
                    {getDel()}
                </div>
            );
        }},
        {name: loc("l_193"), key: 'index', width: 70},
        {name: loc("l_608"), key: 'sn', width: 200},
        {name: loc("l_228"), key: 'name', width: 300},
        {name: loc("l_229"), key: 'tp', width: 90, formatter: (props) => {
            const d = props.row;

            const tmp = tp_list();
            const f = tmp.find(t => t.sn === d.tp);
            if (f) {
                return f.name;
            }

            return loc("l_630");
        }},
        {name: loc("l_218"), key: 'opt', width: 110, formatter: (props) => {
            const d = props.row;
            if (d.opt === "Y") {
                return <Chip flag="Y" label={loc("l_218")} cl="green"/>;
            }

            return "";
        }},
        {name: loc("l_805"), key: 'width', width: 100},
    ];

    const Right = () => {
        const getAdd = () => {
            if (is_empty(umd.value)) {
                return <Btn color="green" hcmd={() => umd.pact(pact, null, "add", {tp: "add", cur: 0, opt: "N"})} className="ml-3">{loc("l_239")}</Btn>;
            }

            return null;
        };

        return (
            <div className="inline-flex">
                <KFile umd={umd} title={`${title}_${loc("l_194")}`} col={["index", "sn", "name", "tp", "opt", "width"]} row={[
                    {index: 1, sn: "sn", name: loc("l_132")},
                    {index: 2, sn: "name", name: loc("l_412")},
                    {index: 3, sn: "tp", name: loc("l_229")},
                    {index: 4, sn: "opt", name: loc("l_218")},
                    {index: 5, sn: "width", name: loc("l_805")},
                ]} hcmd={hImport}/>
                {getAdd()}
            </div>
        );
    };

    return (
        <div className="flex flex-col">
            <PanelFind cl="green" left={title} right={<Right/>} hcmd={umd.setFilter}/>
            <GridTable high={high} col={col} row={getRow} rowHeight={42}/>
            <DlgVal open={open_val} hcmd={v => umd.act(act, v, null, "tp")} setOpen={openVal} data={umd.cur} main={umd.value} set={fix_set}/>
            <DlgMove open={open_move} hcmd={v => umd.act(act, v, null, "tp")} setOpen={openMove} data={umd.cur}/>
            <WaitUmd umd={umd}/>
        </div>
    );
};

export {FieldView};
